<template>
  <div class="wiki-view">
    <!-- 检索区域 -->
    <div class="search-section">
      <div class="search-container">
        <el-form class="search-form" :model="searchFormData">
          <!-- 第一行 -->
          <div class="search-row">
            <el-form-item class="search-item" label="记录人：">
              <el-select class="search-select" placeholder="全部" v-model="searchFormData.sysUserId" clearable filterable
                @change="handleSearch">
                <el-option v-for="item in testOptions" :key="item.id" :label="item.testName" :value="item.id" />
              </el-select>
            </el-form-item>
            <el-form-item class="search-item" label="项目名称：">
              <el-select class="search-select" placeholder="全部" v-model="searchFormData.itemItemId" clearable filterable
                @change="handleSearch">
                <el-option v-for="item in projecOptions" :key="item.ID" :label="item.itemName" :value="item.ID" />
              </el-select>
            </el-form-item>
            <el-form-item class="search-item" label="wiki类型：">
              <el-select class="search-select" placeholder="全部" v-model="searchFormData.itemWIKITypeId"
                clearable filterable @change="handleSearch">
                <el-option v-for="item in wikiOptions" :key="item.ID" :label="item.typeName" :value="item.ID" />
              </el-select>
            </el-form-item>
            <el-form-item class="search-item" label="问题描述：">
              <el-input class="search-input" v-model="searchFormData.problemMsg" placeholder="请输入问题描述" clearable
                @keyup.enter="handleSearch"></el-input>
            </el-form-item>
          </div>
          <!-- 第二行 -->
          <div class="search-row">
            <el-form-item class="search-item" label="时间范围：">
              <el-date-picker class="search-date" v-model="searchFormData.timeFrame" type="daterange" value-format="YYYY-MM-DD"
                format="YYYY-MM-DD" :default-value="defaultDateRange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" />
            </el-form-item>
            <el-form-item class="search-item" label="评分状态：">
              <el-select class="search-select" placeholder="全部" v-model="searchFormData.ratingStatus" clearable @change="handleSearch">
                <el-option label="全部" :value="0" />
                <el-option label="已评分" :value="1" />
                <el-option label="未评分" :value="2" />
              </el-select>
            </el-form-item>
            <div class="search-actions">
              <el-button type="primary" class="search-btn" @click="handleSearch">
                <el-icon><Search /></el-icon>
                搜索
              </el-button>
              <el-button class="export-btn" type="success" @click="handleExport">
                <el-icon :size="16"><Download /></el-icon>
                售后记录
              </el-button>
              <el-button class="export-btn" type="success" @click="handleHotspotExport">
                <el-icon :size="16"><Download /></el-icon>
                热点问题
              </el-button>
            </div>
          </div>
        </el-form>
      </div>
    </div>

    <!-- 表格区域 -->
    <div class="content-section">
      <div class="content-header">
        <div class="header-title">
        </div>
        <div class="header-actions">
          <el-button type="primary" class="add-btn" @click="initDialogForm(null)">
            <el-icon><Plus /></el-icon>
            添加wiki
          </el-button>
        </div>
      </div>

      <!-- 数据展示区域 -->
      <div class="table-container" v-loading="loading">
        <el-table :data="demandsList" border :height="tableHeight + 'px'" style="width: 100%"
          :header-cell-style="tableHeaderStyle" :row-style="tableRowStyle" @row-dblclick="handleViewRequire">
          <el-table-column label="登记人" width="100" align="center">
            <template #="{ row }">
              <span class="user-name">{{ row.createUser }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="projectName" label="项目名称" width="140" align="center" />
          <el-table-column prop="problemMsg" label="问题描述" width="300" align="left" show-overflow-tooltip />
          <el-table-column prop="problemReason" label="问题原因" width="300" align="left" show-overflow-tooltip />
          <el-table-column prop="trueResult" label="处理结果" width="400" align="left" show-overflow-tooltip />
          <el-table-column prop="beginDate" label="开始时间" width="160" sortable :formatter="timeDate" align="center" />
          <el-table-column prop="endDate" label="结束时间" width="160" sortable :formatter="timeDate" align="center" />
          <el-table-column prop="processingDate" label="处理时间" width="140" align="center" />
          <el-table-column label="是否解决" width="100" align="center">
            <template #="{ row }">
              <el-tag :type="row.isTrue == 1 ? 'success' : 'danger'" size="small">
                {{ row.isTrue == 1 ? "已解决" : "未解决" }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column label="操作" align="center" :width="isLiuTao ? '350' : '280'" fixed="right" border>
            <template #="{ row }">
              <div class="table-actions">
                <!-- 查看 -->
                <el-button type="primary" size="small" class="action-btn view-btn" @click="handleViewRequire(row.ID)">
                  <el-icon><View /></el-icon>
                  详情
                </el-button>
                <!-- 修改 -->
                <el-button type="info" size="small" class="action-btn edit-btn" @click="initDialogForm(row)">
                  <el-icon><Edit /></el-icon>
                  编辑
                </el-button>
                <!-- 评分按钮（仅刘涛可见） -->
                <el-button v-if="isLiuTao" :type="row.wikiRateUser ? 'success' : 'warning'" size="small" 
                  :class="['action-btn', row.wikiRateUser ? 'rated-btn' : 'rating-btn']" @click="handleRating(row.ID)">
                  <el-icon><Star /></el-icon>
                  {{ row.wikiRateUser ? '已评价' : '评分' }}
                </el-button>
                <!-- 删除 -->
                <el-popconfirm title="确定要删除该wiki吗？" @confirm="handleDelRequire(row.ID)" @cancel="handleCancelDel"
                  width="200px">
                  <template #reference>
                    <el-button type="danger" size="small" class="action-btn delete-btn">
                      <el-icon><Delete /></el-icon>
                      删除
                    </el-button>
                  </template>
                </el-popconfirm>
              </div>
            </template>
          </el-table-column>
        </el-table>
      </div>

      <!-- 分页区域 -->
      <div class="pagination-container">
        <Pagination
          :total="paginationTotal"
          :page-size="pageInfo.pageSize"
          @uadate:currentPage="handleCurrentChange"
          @update:pageSize="handleSizeChange"
        />
      </div>
    </div>

    <!-- 添加/修改需求弹窗 -->
    <el-dialog id="dialogForm" v-model="dialogTableVisible" :title="titleDialogText + 'wiki'" width="1000px"
      :show-close="true" :before-close="handleBeforeCancel" class="modern-dialog">
      <el-form class="dialog-form" :inline="true" ref="dialogFormRef" :model="dialogFormData" :rules="ruleDialogForm"
        label-position="left" label-width="110px">
        <el-form-item label="项目名称：" prop="itemItemId" required>
          <el-select style="width: 200px" placeholder="请选择项目" v-model="dialogFormData.itemItemId" clearable>
            <el-option v-for="item in projecOptions" :key="item.ID" :label="item.itemName" :value="item.ID" />
          </el-select>
        </el-form-item>

        <el-form-item label="wiki类型：" prop="itemWIKITypeId" required style="margin-left: 210px">
          <el-select style="width: 200px" placeholder="请选择类型" v-model="dialogFormData.itemWIKITypeId" clearable>
            <el-option v-for="wiki in wikiOptions" :key="wiki.ID" :label="wiki.typeName" :value="wiki.ID" />
          </el-select>
        </el-form-item>

        <el-form-item label="问题描述：" prop="problemMsg" required>
          <el-input v-model="dialogFormData.problemMsg" placeholder="请输入问题描述"
            :input-style="{ width: '740px' }"></el-input>
        </el-form-item>
        <el-form-item label="问题原因：" prop="problemReason" required>
          <el-input v-model="dialogFormData.problemReason" placeholder="请输入问题原因"
            :input-style="{ width: '740px' }"></el-input>
        </el-form-item>
        <el-form-item label="处理情况：" prop="trueResult" required>
          <el-input v-model="dialogFormData.trueResult" placeholder="请输入处理情况"
            :input-style="{ width: '740px' }"></el-input>
        </el-form-item>
        <el-form-item label=" 开始时间：" prop="beginDate" required>
          <el-date-picker v-model="dialogFormData.beginDate" type="datetime" placeholder="请选择日期"
            value-format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm:ss"
            :disabled-date="disabledBeginDate"
          />
        </el-form-item>
        <el-form-item label=" 结束时间：" prop="endDate" required style="margin-left: 170px">
          <el-date-picker v-model="dialogFormData.endDate" type="datetime" placeholder="请选择日期"
            value-format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm:ss" :disabled-date="disabledEndDate" />
        </el-form-item>
        <el-form-item label="参与人：" prop="auxiliaryUser">
          <el-input v-model="dialogFormData.auxiliaryUser" placeholder="请输入参与人"
            :input-style="{ width: '740px' }"></el-input>
        </el-form-item>
        <el-form-item label="研发响应时间：" prop="developmentBBTime">
          <el-input v-model="dialogFormData.developmentBBTime" placeholder="请输入研发响应时间"
            :input-style="{ width: '740px' }"></el-input>
        </el-form-item>
        <el-form-item label="是否解决" prop="isTrue" required>
          <el-select style="width: 160px" placeholder="请选择" v-model="dialogFormData.isTrue" clearable>
            <el-option :key="1" label="是" :value="1" />
            <el-option :key="2" label="否" :value="2" />
          </el-select>
        </el-form-item>
        <el-form-item label="处理留证" prop="problemPhoto" required>
          <EditorVue class="editor" :modelValue="dialogFormData.problemPhoto" @update:modelValue="updateModelValue"
            style="width: 760px;" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="handleCancel">取消</el-button>
          <el-button type="primary" @click="handleAddRequire"> 确定 </el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 查看需求 -->
    <el-dialog class="dialog-view-container modern-dialog" title="WIKI详细信息" :show-close="true" width="1200px"
      v-model="dialogViewVisible" style="height: 750px;overflow: auto;">
      <div class="view-content">
        <el-row :gutter="20">
          <el-col :span="3">
            <span class="dialog-view-requireTitle">项目名称:</span>
          </el-col>
          <el-col :span="5">{{ dialogViewData.projectName }}</el-col>
          <el-col :span="3">
            <span class="dialog-view-requireTitle">wiki类型:</span>
          </el-col>
          <el-col :span="5">{{ dialogViewData.itemWIKITypeName }}</el-col>
          <el-col :span="3">
            <span class="dialog-view-requireTitle">创建人:</span>
          </el-col>
          <el-col :span="5">{{ dialogViewData.createUser }}</el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="3">
            <span class="dialog-view-requireTitle">问题原因:</span>
          </el-col>
          <el-col :span="10">{{ dialogViewData.problemReason }}</el-col>
          <el-col :span="3">
            <span class="dialog-view-requireTitle">问题描述:</span>
          </el-col>
          <el-col :span="8">{{ dialogViewData.problemMsg }}</el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="3">
            <span class="dialog-view-requireTitle">处理结果:</span>
          </el-col>
          <el-col :span="21">{{ dialogViewData.trueResult }}</el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="3">
            <span class="dialog-view-requireTitle">开始时间:</span>
          </el-col>
          <el-col :span="5">{{ dialogViewData.beginDate }}</el-col>
          <el-col :span="3">
            <span class="dialog-view-requireTitle">结束时间:</span>
          </el-col>
          <el-col :span="5">{{ dialogViewData.endDate }}</el-col>
          <el-col :span="3">
            <span class="dialog-view-requireTitle">处理时间:</span>
          </el-col>
          <el-col :span="5">{{ dialogViewData.processingDate }}</el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="3">
            <span class="dialog-view-requireTitle">辅助处理人:</span>
          </el-col>
          <el-col :span="3">{{ dialogViewData.auxiliaryUser }}</el-col>
          <el-col :span="2">
            <span class="dialog-view-requireTitle">是否解决:</span>
          </el-col>
          <el-col :span="2">
            <el-tag :type="dialogViewData.isTrue == 1 ? 'success' : 'danger'" size="small">
              {{ dialogViewData.isTrue == 1 ? "是" : "否" }}
            </el-tag>
          </el-col>
          <el-col :span="2">
            <span class="dialog-view-requireTitle">是否归档:</span>
          </el-col>
          <el-col :span="2">
            <el-tag :type="dialogViewData.isArchiving == 1 ? 'success' : 'info'" size="small">
              {{ dialogViewData.isArchiving == 1 ? "是" : "否" }}
            </el-tag>
          </el-col>
          <el-col :span="2">
            <span class="dialog-view-requireTitle">归档地址:</span>
          </el-col>
          <el-col :span="8">{{ dialogViewData.archivingUrl }}</el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="3">
            <span class="dialog-view-requireTitle">处理留证:</span>
          </el-col>
          <el-col :span="21">
            <el-scrollbar style="max-height: 500px">
              <div ref="content" :style="requirementContetnStyle" v-dompurify-html="dialogViewData.problemPhoto"
                @click="showImg($event)"></div>
            </el-scrollbar>
          </el-col>
        </el-row>
      </div>
    </el-dialog>

    <!-- 查看大图 -->
    <div class="page-shade" v-if="isShowBigImg">
      <div class="img-big" @click="isShowBigImg = false" @mousewheel="mousewheel">
        <img :src="curPhoto.url" alt="大图" @click="isShowBigImg = false" :style="{
          transform: `rotate(${curPhoto.rotate}deg) scale(${curPhoto.scale})`,
          width: `${curPhoto.w}px`
        }" />
      </div>
    </div>

    <!-- 上传、审核用例 -->
    <el-dialog v-model="dialogTestVisible" title="需求用例" width="80%" :show-close="true" :before-close="closeCasesDialog" class="modern-dialog">
      <!-- 上传用例 -->
      <el-upload ref="uploadCase" class="upload-demo" action="#" :limit="1" :before-upload="handleBeforeUpload">
        <template #trigger>
          <el-button type="primary">上传用例</el-button>
        </template>
        <template #tip>
          <p>{{ uploadTipText }}</p>
        </template>
      </el-upload>
      <!-- 用例数据表格 -->
      <el-scrollbar max-height="600px">
        <el-table height="600px" :data="initCaseData" border>
          <el-table-column fixed type="index" label="序号" width="60" align="center" />
          <el-table-column label="用例名称" min-width="200" header-align="center" property="caseName" show-overflow-tooltip
            fixed="left" border>
            <template #="{ row }">
              <span class="cell-ellipsis">{{ row.caseName }}</span>
            </template>
          </el-table-column>
          <el-table-column label="用例编写人" width="100" align="center" property="caseEditMembers"></el-table-column>
          <el-table-column label="更新时间" width="120" align="center" property="caseEditDate" sortable
            :formatter="timeDate"></el-table-column>
          <el-table-column label="用例得分" width="100" align="center" property="caseScore"></el-table-column>
          <el-table-column label="是否能复用" width="100" align="center" property="isCaseReuse">
            <template #="{ row }">
              <el-tag :type="row.isCaseReuse == '否' ? 'danger' : 'success'" size="small">
                {{ row.isCaseReuse }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column label="是否是补充用例" width="100" align="center" property="isCaseAdd">
            <template #="{ row }">
              <el-tag :type="row.isCaseAdd == '否' ? 'danger' : 'success'" size="small">
                {{ row.isCaseAdd }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column label="用例质量" width="100" align="center" property="caseQuality">
            <template #="{ row }">
              <el-tag :type="getQualityColor(row.caseQuality)" size="small">
                {{
                  row.caseQuality === 3
                    ? "优"
                    : row.caseQuality === 2
                      ? "良"
                      : "差"
                }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column label="审核状态" width="100" align="center" property="isAudit">
            <template #="{ row }">
              <el-tag :type="row.isAudit == 0 ? 'danger' : 'success'" size="small">
                {{ row.isAudit === 0 ? "未审核" : "已审核" }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column label="操作" align="center" width="180" fixed="right" border>
            <template #="{ row }">
              <div class="table-actions">
                <!-- 审核 -->
                <el-button class="table-operation table-operation-view" @click="handleAuditTest(row)">
                  <el-icon><SetUp /></el-icon>
                </el-button>
                <!-- 修改 -->
                <el-button id="addBtn" class="table-operation table-operation-edit" @click="handleEditTest(row)">
                  <el-icon><Edit /></el-icon>
                </el-button>
                <!-- 删除 -->
                <el-popconfirm title="确定要删除该需求吗？" @confirm="handleDelTest(row.ID)" @cancel="handleCancelDel"
                  width="200px">
                  <template #reference>
                    <el-button class="table-operation table-operation-del">
                      <el-icon><Delete /></el-icon>
                    </el-button>
                  </template>
                </el-popconfirm>
              </div>
            </template>
          </el-table-column>
        </el-table>
      </el-scrollbar>
    </el-dialog>

    <!-- 修改用例弹窗 -->
    <el-dialog title="用例详情" v-model="caseVisible" :show-close="true" :before-close="closeCaseDialog" class="modern-dialog">
      <el-form ref="caseDlgFormRef" v-model="caseDlgFormData">
        <el-form-item label="用例名称:">
          <el-input type="text" v-model="caseDlgFormData.caseName" placeholder="请输入用例名称" />
        </el-form-item>
        <el-form-item label="操作步骤:">
          <el-input type="textarea" :rows="5" v-model="caseDlgFormData.operationSteps" placeholder="请输入操作步骤">
          </el-input>
        </el-form-item>
        <el-form-item label="预期结果:">
          <el-input type="textarea" :rows="5" v-model="caseDlgFormData.expectedResult" placeholder="请输入预期结果" />
        </el-form-item>
        <el-form-item label="实际结果:">
          <el-input type="textarea" :rows="5" v-model="caseDlgFormData.realResult" placeholder="请输入实际结果" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="closeCaseDialog">取消</el-button>
          <el-button type="primary" @click="submitCaseFormData">
            确认
          </el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 是否归档弹框 -->
    <el-dialog v-model="dialogWikiIsArchivingVisible" :show-close="true" :before-colse="closeWikiArchivingDialog"
      title="wiki归档" class="modern-dialog">
      <!-- 审核用例 -->
      <el-form ref="archivingFormRef" :model="archivingFormData">
        <el-form-item label="归档地址：">
          <el-input v-model="archivingFormData.archivingUrl" />
        </el-form-item>
        <el-form-item label="是否归档：">
          <el-switch v-model="archivingFormData.isArchiving" inline-prompt :active-value="1" :inactive-value="0" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="closeWikiArchivingDialog">取消</el-button>
          <el-button type="primary" @click="submitWikiArchivingFormData">
            确认
          </el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 评分弹框 -->
    <el-dialog v-model="dialogRatingVisible" :title="getRatingDialogTitle()" width="500px" :show-close="true" 
      :before-close="closeRatingDialog" class="modern-dialog">
      <el-form ref="ratingFormRef" :model="ratingFormData" label-width="80px">
        <!-- 显示评价人信息（如果已评价） -->
        <el-form-item v-if="getCurrentWikiRateUser()" label="评价人：">
          <el-tag type="info">{{ getCurrentWikiRateUser() }}</el-tag>
        </el-form-item>
        <el-form-item label="评分：">
          <el-rate
            v-model="ratingFormData.score"
            :max="5"
            show-score
            text-color="#ff9900"
            score-template="{value} 分"
            :allow-half="false"
          />
        </el-form-item>
        <el-form-item label="评价：">
          <el-input
            v-model="ratingFormData.comment"
            type="textarea"
            :rows="4"
            placeholder="请输入评价内容（可选）"
            maxlength="200"
            show-word-limit
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="closeRatingDialog">取消</el-button>
          <el-button type="primary" @click="submitRating">
            确认评分
          </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import EditorVue from "./editor.vue";
import { onMounted, ref, reactive, nextTick, watch, onUnmounted, onActivated, computed } from "vue";
import {
  getTestList,
  getItemList,
  getRequirementCase,
  postUploadCaseFile,
  postRequirementCase,
  delCaseByid,
  putWikiArchiving,
  putEditeCaseByid,
  getWikiTypeList,
  postAddWIki,
  getWikiList,
  getWikiMsg,
  editWikiMsg,
  delWiki,
  getWikiTypeById,
  WikiRate,
  // exportWikis,
} from "@/api/project/index";
import { ElMessage } from "element-plus";
import Pagination from "@/components/Pagenation/index.vue";
import {
  removeEmptyLines,
  tableTimeDateMsg,
  downloadFromEndpoint,
} from "@/utils/utils";
import dayjs from 'dayjs';
import { useRouter } from 'vue-router'
import { Search, Download, Plus, View, Edit, Delete, SetUp, Star } from '@element-plus/icons-vue';
import useUserStore from "@/store/modules/user";
const router = useRouter()
const userStore = useUserStore()

//* 变量声明
const loading = ref(false);
const demandsList = ref<any>([]); //所有需求数据列表
const projecOptions = ref<any>([]); //所有项目下拉列表
const wikiOptions = ref<any>([]); //所有项目下拉列表
const testOptions = ref<any>([]); //所有的测试人员下拉列表

//* 评分相关
const dialogRatingVisible = ref(false); //评分弹窗控件
const ratingFormData = reactive({
  wikiId: null as number | null,
  score: 2,
  comment: ''
});

// 判断当前用户是否为刘涛
const isLiuTao = computed(() => {
  return userStore.userInfo.nickName === '刘涛';
});

//* 弹窗部分
const isCreateDialog = ref(false); //是否创建需求
const titleDialogText = ref(""); //添加或修改标题文本

const dialogWikiIsArchivingVisible = ref(false); //是否归档弹框
const dialogTableVisible = ref(false); //添加/修改需求弹窗控件
const dialogViewVisible = ref(false); //查看需求弹窗控件
const dialogTestVisible = ref(false); //查看、上传、审核用例弹窗控件
const caseVisible = ref(false); //修改用例弹窗控件
const auditVisible = ref(false); //审核用例弹窗控件

const uploadCaseFile = ref<File>(); //待上传文件
const uploadTipText = ref(""); //提示文字
const reqData = reactive({
  id: null,
  page: 1,
  pageSize: 999,
}); //获取当前需求所有用例的请求参数初始值
const reqCaseData = reactive({
  requirementId: null,
  itemItemId: null,
  filePath: "",
}); //导入用例请求参数

const initCaseData = ref<any>([]); //用例表格初始值

const dialogFormRef = ref(); //添加/修改需求表单实例
const requireID = ref(); //需求id

// 初始化表单数据
const initDialogFormData = () => ({
  itemItemId: 1,
  itemWIKITypeId: 1,
  beginDate: '',
  endDate: '',
  auxiliaryUser: "",
  developmentBBTime: "",
  isTrue: 1,
  isArchiving: 0,
  archivingUrl: "",
  problemReason: "",
  trueResult: "",
  problemMsg: "",
  problemPhoto: "",
});
const dialogFormData: any = reactive(initDialogFormData());

// 自定义表单规则
const validatorTmName = (rule: any, value: any, callBack: any) => {
  console.log(rule);
  console.log(value.includes("img src"));
  // 校验通过
  if (value.includes("img src")) {
    callBack();
  } else {
    // 检验未通过
    callBack(new Error("必须包含截图"));
  }
};
// 弹窗表单校验规则
const ruleDialogForm = reactive({
  projectid: [
    {
      itemItemId: true,
      message: "请选择项目名称",
      trigger: "blur",
    },
  ],
  itemWIKITypeId: [
    {
      required: true,
      message: "请选择wiki类型",
      trigger: "blur",
    },
  ],
  problemMsg: [
    {
      required: true,
      message: "请输入问题描述",
      trigger: "blur",
    },
  ],
  problemReason: [
    {
      required: true,
      message: "请输入问题原因",
      trigger: "blur",
    },
  ],
  trueResult: [
    {
      required: true,
      message: "请输入处理情况",
      trigger: "blur",
    },
  ],
  beginDate: [
    {
      required: true,
      message: "请选择开始时间",
      trigger: "blur",
    },
  ],
  endDate: [
    {
      required: true,
      message: "请选择结束时间",
      trigger: "blur",
    },
  ],
  isTrue: [
    {
      required: true,
      message: "请选择是否解决",
      trigger: "blur",
    },
  ],
  problemPhoto: [
    {
      required: true,
      validator: validatorTmName,
      trigger: "blur",
    },
  ],
});

const pageInfo = reactive({
  total: 0, //总条目
  page: 1, //当前页码
  pageSize: 20, //当前每页条数
});
//关键词数据默认值
const searchFormData = ref({
  itemItemId: null,
  sysUserId: null,
  itemWIKITypeId: null,
  isTrue: null,
  problemMsg: "",
  ratingStatus: 0, // 评分状态：0-全部，1-已评分，2-未评分
  timeFrame: [
    dayjs().startOf('month').format('YYYY-MM-DD'),
    dayjs().format('YYYY-MM-DD')
  ] as string[],
});

const tableHeaderStyle = {
  backgroundColor: "#F2F6FC",
  color: "#909399",
  textAlign: "center",
};

// 规避 total 为 0 时 el-pagination 不渲染的情况（例如首次加载接口未返回前）
const paginationTotal = computed(() => {
  return pageInfo.total > 0 ? pageInfo.total : 1;
});
const tableRowStyle = {
  cursor: "pointer",
  backgroundColor: "#fff",
};

const requirementContetnStyle: { [key: string]: string } = {
  whiteSpace: "wrap",
  lineHeight: "200%",
  cursor: "pointer",
};

// 查看wiki初始值
const dialogViewData: any = reactive({
  id: 0,
  createUser: "",
  projectName: 0,
  processingDate: "",
  beginDate: "0001-01-01T00:00:00Z",
  endDate: "0001-01-01T00:00:00Z",
  auxiliaryUser: "",
  developmentBBTime: "",
  isTrue: 0,
  isArchiving: 0,
  archivingUrl: "",
  problemReason: "",
  trueResult: "",
  problemMsg: "",
  problemPhoto: "",
  itemWIKITypeName: "",
});

//? 修改用例
// 表单实例
const caseDlgFormRef = ref();
// 表单初始化方法
const initCaseDlgFormData = () => ({
  id: null,
  caseName: "",
  operationSteps: "",
  expectedResult: "",
  realResult: "",
});
// 图片放大功能
const dialogVisible = ref(false);
const currentImageSrc = ref("");
const content = ref<HTMLElement | null>(null);
//表单初始值
const caseDlgFormData = reactive(initCaseDlgFormData());

//? 是否归档
const archivingFormRef = ref();
const initArchivingFormData = () => ({
  id: null,
  archivingUrl: <any>"",
  isArchiving: 0,
});
const archivingFormData = reactive(initArchivingFormData());

//* 功能函数
// @ts-ignore 时间格式化
const timeDate = (row: any, column: any, cellValue: any, index: number) => {
  return tableTimeDateMsg(cellValue);
};

// 获取所有wiki数据列表-demandsList
const getDemandsList = async () => {
  loading.value = true;

  const resData = await getWikiList({
    itemItemId:
      searchFormData.value.itemItemId != "" ? searchFormData.value.itemItemId : null,
    sysUserId: searchFormData.value.sysUserId != "" ? searchFormData.value.sysUserId : null,
    isTrue: searchFormData.value.isTrue != "" ? searchFormData.value.isTrue : null,
    itemWIKITypeId:
      searchFormData.value.itemWIKITypeId != ""
        ? searchFormData.value.itemWIKITypeId
        : null,
    problemMsg: searchFormData.value.problemMsg,
    ratingStatus: searchFormData.value.ratingStatus,
    beginDate:
      searchFormData.value.timeFrame[0],
    endDate:
      searchFormData.value.timeFrame[1],
    page: pageInfo.page,
    pageSize: pageInfo.pageSize,
  });
  if (resData.data.code === 200 && resData.data.data.list !== null) {
    pageInfo.total = resData.data.data.total;
    pageInfo.page = resData.data.data.page;
    pageInfo.pageSize = resData.data.data.pageSize;
    demandsList.value = resData.data.data.list; //所有需求数据列表
  } else {
    ElMessage.error(resData.data.msg);
    loading.value = false;
    return;
  }
  loading.value = false;
};
// 更改每页条目数
const handleSizeChange = async (val: any) => {
  pageInfo.pageSize = val;
  pageInfo.page = 1;
  await getDemandsList();
};
// 更改当前页码
const handleCurrentChange = async (val: any) => {
  pageInfo.page = val;
  await getDemandsList();
};

// 获取所有项目下拉列表-projecOptions
const getProjectOptons = async () => {
  loading.value = true;
  const resData = await getItemList({});
  if (resData.data.code === 200 && resData.data.data.length != 0) {
    // 所有项目下拉列表
    projecOptions.value = resData.data.data.map((item: any) => {
      return { ID: item.ID, itemName: item.itemName };
    });
  } else {
    ElMessage.error("未获取到项目数据列表");
    loading.value = false;
    return;
  }
  loading.value = false;
};

// 获取所有wiki类型下拉列表-getWikiTypeOptons
const getWikiTypeOptons = async () => {
  loading.value = true;
  const resData = await getWikiTypeList();
  if (resData.data.code === 200 && resData.data.data.length != 0) {
    // 所有项目下拉列表
    wikiOptions.value = resData.data.data.map((wiki: any) => {
      return { ID: wiki.ID, typeName: wiki.typeName };
    });
  } else {
    ElMessage.error("未获取到项目数据列表");
    loading.value = false;
    return;
  }
  loading.value = false;
};

// 获取所有测试人员列表-testOptions
const getAllTestOptions = async () => {
  loading.value = true;
  const resData = await getTestList();
  if (resData.data.code === 200 && resData.data.data.length != 0) {
    // 所有测试人员下拉列表
    testOptions.value = resData.data.data.map((item: any) => {
      return { id: item.uuid, testName: item.userName };
    });
  } else {
    ElMessage.error("未获取到测试人员列表");
    loading.value = false;
    return;
  }
  loading.value = false;
};

// 搜索功能
const handleSearch = async () => {
  loading.value = true;
  await getDemandsList();
  loading.value = false;
};

// 是否显示大图
const isShowBigImg = ref(false);
// 当前大图的信息
const curPhoto = ref({
  url: "", //照片地址
  name: "", //照片名称
  rotate: 0, //旋转角度
  scale: 1, //缩放比例
  w: 0, //照片宽度
  h: 0, // 照片高度
});
// 显示大图
const showImg = (event: MouseEvent) => {
  const target = event.target as HTMLElement;
  if (target.tagName === 'IMG') {
    const targetImage = target as HTMLImageElement;
    curPhoto.value.url = targetImage.src;
    curPhoto.value.rotate = 0;
    curPhoto.value.scale = 1;
    // 确保图片加载完成
    const img = new Image();
    img.onload = () => {
      curPhoto.value.w = img.width; // 使用图片的原始宽度
      curPhoto.value.h = img.height; // 使用图片的原始高度
      isShowBigImg.value = true;
    };
    img.src = targetImage.src;
  }
};

// 鼠标滚动事件
const mousewheel = (e: WheelEvent) => {
  e.preventDefault(); // 阻止默认行为
  const isZoomingIn = e.deltaY < 0; // deltaY < 0 表示向上滚动（放大）
  const zoomStep = 0.1; // 每次滚动的缩放步长
  if (isZoomingIn) {
    // 放大
    if (curPhoto.value.scale < 2) { // 最大缩放比例限制
      curPhoto.value.scale += zoomStep;
    }
  } else {
    // 缩小
    if (curPhoto.value.scale > 0.3) { // 最小缩放比例限制
      curPhoto.value.scale -= zoomStep;
    }
  }
  // 确保缩放比例在合理范围内
  curPhoto.value.scale = Math.max(0.3, Math.min(2, curPhoto.value.scale));
};

// //! 导出功能
// const downloadFromEndpoint = async (endpoint: any, Data: any) => {
//   try {
//     const response = await request({
//       url: endpoint,
//       method: "POST",
//       responseType: "blob", // 重要：设置响应类型为 blob
//       data: Data, // 添加请求参数
//       headers: {
//         "Content-Type": "application/json", // 根据实际情况设置请求头
//       },
//     });
//     const blob = new Blob([response.data], {
//       type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8",
//     });
//     const url = window.URL.createObjectURL(blob);
//     const link = document.createElement("a");
//     link.href = url;
//     link.setAttribute("download", "export.xlsx");
//     link.style.visibility = "hidden";
//     document.body.appendChild(link);
//     link.click();
//     document.body.removeChild(link);
//   } catch (error) {
//     console.error("下载文件出错:", error);
//   }
// };

const handleExport = async () => {
  loading.value = true;

  const postData = {
    itemItemId:
      searchFormData.value.itemItemId != "" ? searchFormData.value.itemItemId : null,
    sysUserId: searchFormData.value.sysUserId != "" ? searchFormData.value.sysUserId : null,
    isTrue: searchFormData.value.isTrue != "" ? searchFormData.value.isTrue : null,
    itemWIKITypeId:
      searchFormData.value.itemWIKITypeId != ""
        ? searchFormData.value.itemWIKITypeId
        : null,
    problemMsg: searchFormData.value.problemMsg,
    ratingStatus: searchFormData.value.ratingStatus,
    beginDate:
      searchFormData.value.timeFrame[0],
    endDate:
      searchFormData.value.timeFrame[1],
  };

  downloadFromEndpoint("POST", "/wiki/exportThisMonthWikis", postData);

  loading.value = false;
};
const handleHotspotExport = async () => {
  loading.value = true;

  const postData = {
    itemItemId:
      searchFormData.value.itemItemId != "" ? searchFormData.value.itemItemId : null,
    sysUserId: searchFormData.value.sysUserId != "" ? searchFormData.value.sysUserId : null,
    isTrue: searchFormData.value.isTrue != "" ? searchFormData.value.isTrue : null,
    itemWIKITypeId:
      searchFormData.value.itemWIKITypeId != ""
        ? searchFormData.value.itemWIKITypeId
        : null,
    problemMsg: searchFormData.value.problemMsg,
    ratingStatus: searchFormData.value.ratingStatus,
    beginDate:
      searchFormData.value.timeFrame[0],
    endDate:
      searchFormData.value.timeFrame[1],
  };

  downloadFromEndpoint("POST", "/wiki/exportThisMonthHotspot", postData);

  loading.value = false;
};

// 选择文件后临时保存
const handleBeforeUpload = async (file: any) => {
  uploadCaseFile.value = file;
  if (uploadCaseFile.value == undefined) {
    uploadTipText.value = "请先选择用例";
  } else {
    // 选择并上传用例
    const resData = await postUploadCaseFile(uploadCaseFile.value);
    // 上传成功则直接导入用例
    if (resData.data.code === 200) {
      ElMessage.success(resData.data.msg);
      reqCaseData.filePath = resData.data.data.filePath;

      // 导入用例
      const resCaseData = await postRequirementCase(reqCaseData);
      // 导入用例成功则刷新用例表格
      if (resCaseData.data.code === 200) {
        ElMessage.success(resCaseData.data.msg);
        await getDemandsList();

        // 重新获取用例
        const resDataList = await getRequirementCase(reqData);
        if (
          resDataList.data.code === 200 &&
          resDataList.data.data.list !== null
        ) {
          initCaseData.value = resDataList.data.data.list;
        } else {
          // 获取用例失败提示
          ElMessage.error(resDataList.data.msg);
          throw Error(resDataList.data.msg);
        }
      } else {
        // 导入失败提示
        ElMessage.error(resCaseData.data.msg);
        throw Error(resCaseData.data.msg);
      }
    } else {
      // 上传失败提示
      ElMessage.error(resData.data.msg);
      throw new Error(resData.data.msg);
    }
  }
  return false;
};

// 关闭/取消用例弹窗事件
const closeCasesDialog = () => {
  dialogTestVisible.value = false; //关闭弹窗
  reqData.id = null;
  reqCaseData.filePath = "";
  reqCaseData.itemItemId = null;
  reqCaseData.requirementId = null;
};
// 关闭/取消修改用例弹窗事件
const closeCaseDialog = () => {
  caseVisible.value = false; //关闭弹窗
  initCaseDlgFormData(); //初始化表单数据
};

// 关闭/取消审核用例弹窗事件
const closeWikiArchivingDialog = () => {
  dialogWikiIsArchivingVisible.value = false;
  initArchivingFormData();
};

// 定义不同用例质量的颜色
const getQualityColor = (quality: number) => {
  switch (quality) {
    case 3:
      return "green"; // 优 - 绿色
    case 2:
      return "blue"; // 良 - 蓝色
    default:
      return "red"; // 差 - 红色
  }
};

// 选择开始时间后校验（用watch监听变化）
watch(() => dialogFormData.beginDate, (val) => {
  if (!val) return;
  const selected = new Date(val).getTime();
  const now = Date.now();
  if (selected > now) {
    dialogFormData.beginDate = '';
    ElMessage.warning('开始时间不能晚于当前时间！');
  }
});

// 选择结束时间后校验（结束时间不能早于开始时间，且不能晚于当前时间）
watch(() => dialogFormData.endDate, (val) => {
  if (!val) return;
  const endTs = new Date(val).getTime();
  const now = Date.now();
  if (endTs > now) {
    dialogFormData.endDate = '';
    ElMessage.warning('结束时间不能晚于当前时间！');
    return;
  }
  if (dialogFormData.beginDate) {
    const beginTs = new Date(dialogFormData.beginDate).getTime();
    if (endTs < beginTs) {
      dialogFormData.endDate = '';
      ElMessage.warning('结束时间不能早于开始时间！');
    }
  }
});

// 禁止选择未来日期（用于开始时间日期粒度）
const disabledBeginDate = (date: Date) => {
  const endOfToday = new Date();
  endOfToday.setHours(23, 59, 59, 999);
  return date.getTime() > endOfToday.getTime();
};

// 禁止选择未来日期，且不得早于开始日期（用于结束时间日期粒度）
const disabledEndDate = (date: Date) => {
  const endOfToday = new Date();
  endOfToday.setHours(23, 59, 59, 999);
  if (date.getTime() > endOfToday.getTime()) return true;
  if (!dialogFormData.beginDate) return false;
  const startDay = new Date(dialogFormData.beginDate);
  startDay.setHours(0, 0, 0, 0);
  return date.getTime() < startDay.getTime();
};

// 确认删除用例
const handleDelTest = async (id: number) => {
  const resData = await delCaseByid(id);
  if (resData.data.code === 200) {
    ElMessage.success(resData.data.msg);
    // 重新获取用例
    const resDataList = await getRequirementCase(reqData);
    if (resDataList.data.code === 200 && resDataList.data.data.list !== null) {
      initCaseData.value = resDataList.data.data.list;
    } else {
      // 获取用例失败提示
      ElMessage.error(resDataList.data.msg);
      throw Error(resDataList.data.msg);
    }
  } else {
    ElMessage.error(resData.data.msg);
    throw new Error();
  }
};
// 提交归档数据数据
const submitWikiArchivingFormData = async () => {
  const resData = await putWikiArchiving(archivingFormData);
  if (resData.data.code == 200) {
    ElMessage.success(resData.data.msg);
    dialogWikiIsArchivingVisible.value = false;
  } else {
    ElMessage.error(resData.data.msg);
    throw new Error(resData.data.msg);
  }
  await getDemandsList();
  auditVisible.value = false;
};

// 审核功能
const handleAuditTest = (row: any) => {
  console.log("审核：", row);
};

// 开启修改用例弹窗
const handleEditTest = (row: any) => {
  caseVisible.value = true;
  initCaseDlgFormData(); //表单初始化
  caseDlgFormData.id = row.ID;
  caseDlgFormData.caseName = row.caseName;
  caseDlgFormData.operationSteps = row.operationSteps;
  caseDlgFormData.expectedResult = row.expectedResult;
  caseDlgFormData.realResult = row.realResult;
};

// 提交修改后的用例
const submitCaseFormData = async () => {
  const resData = await putEditeCaseByid(caseDlgFormData);
  if (resData.data.code == 200) {
    ElMessage.success(resData.data.msg);
    // 重新获取用例
    const resDataList = await getRequirementCase(reqData);
    if (resDataList.data.code === 200 && resDataList.data.data.list !== null) {
      initCaseData.value = resDataList.data.data.list;
    } else {
      // 获取用例失败提示
      ElMessage.error(resDataList.data.msg);
      throw Error(resDataList.data.msg);
    }
  } else {
    ElMessage.error(resData.data.msg);
    throw new Error(resData.data.msg);
  }
  caseVisible.value = false;
};

//* 添加/修改弹窗表单校验
const validateForm = (form: any) => {
  return new Promise<boolean>((resolve, reject) => {
    form.validate((valid: boolean) => {
      if (valid) {
        resolve(true);
      } else {
        reject(new Error("请按要求填写需求！"));
      }
    });
  });
};

// 开启添加/修改wiki弹窗
const initDialogForm = async (row: any) => {
  dialogTableVisible.value = true;
  initDialogFormData(); //表单初始化
  if (row !== null) {
    //* 修改wiki
    isCreateDialog.value = false;
    titleDialogText.value = "修改";
    // 其它非测试人员默认为其它
    if (row.ItemItemId == 0) {
      dialogFormData.projectid = 32;
    } else {
      dialogFormData.projectid = row.ItemItemId; //项目ID
    }
    requireID.value = row.ID; //wiki ID
    const resData = await getWikiMsg(row.ID); //根据wiki id获取详细信息
    const data = resData.data.data;
    if (resData.data.code === 7) {
      ElMessage.error(resData.data.msg);
      throw new Error();
    } else {
      dialogFormData.createUser = data.createUser;
      dialogFormData.itemWIKITypeId = data.itemWIKITypeId;
      dialogFormData.itemItemId = data.itemItemId;
      dialogFormData.projectName = data.projectName;
      dialogFormData.beginDate = data.beginDate;
      dialogFormData.endDate = data.endDate;
      dialogFormData.auxiliaryUser = data.auxiliaryUser;
      dialogFormData.developmentBBTime = data.developmentBBTime;
      dialogFormData.isTrue = data.isTrue;
      dialogFormData.isArchiving = data.isArchiving;
      dialogFormData.archivingUrl = data.archivingUrl;
      dialogFormData.problemReason = data.problemReason;
      dialogFormData.trueResult = data.trueResult;
      dialogFormData.problemMsg = data.problemMsg;
      // 去除空行
      dialogFormData.problemPhoto = removeEmptyLines(data.problemPhoto);
    }
  } else {
    //* 添加需求
    isCreateDialog.value = true;
    titleDialogText.value = "添加";
    // 修复下拉框默认显示1的问题
    if (projecOptions.value && projecOptions.value.length > 0) {
      dialogFormData.itemItemId = projecOptions.value[0].ID;
    } else {
      dialogFormData.itemItemId = null;
    }
    if (wikiOptions.value && wikiOptions.value.length > 0) {
      dialogFormData.itemWIKITypeId = wikiOptions.value[0].ID;
    } else {
      dialogFormData.itemWIKITypeId = null;
    }
  }
};

const defaultDateRange = [
  dayjs().startOf('month').toDate(),
  dayjs().toDate()
];

// 富文本数据更新
const updateModelValue = (newContent: any) => {
  dialogFormData.problemPhoto = newContent;
  return dialogFormData.problemPhoto;
};

//添加wiki
const handleTrue = async () => {
  const resData = await postAddWIki(dialogFormData).finally(() => {
    loading.value = false;
    Object.assign(dialogFormData, initDialogFormData());
  });
  if (resData.data.code == 200) {
    ElMessage.success(`${titleDialogText.value}WIKI成功！`);
    await getDemandsList(); //重新获取所有wiki数据
    dialogTableVisible.value = false;
  } else {
    ElMessage.error(resData.data.msg);
    throw new Error();
  }
};

//* 确定添加/修改需求功能
const handleAddRequire = async () => {
  loading.value = true;
  // 确定时监听富文本内容
  const addBtn = document.querySelector("#addBtn");
  addBtn?.addEventListener("update:modelValue", updateModelValue);

  // 提交需求到服务器
  if (isCreateDialog.value) {
    // * 添加需求
    dialogFormData.id = undefined;
    await validateForm(dialogFormRef.value);

    handleTrue();
  } else {
    // * 修改需求
    dialogFormData.id = requireID.value;
    // 需要转下时间格式
    // 创建一个Date对象
    // const begindateObj = ref('');
    // const endDateObj = ref('');
    // // 转换为指定格式
    // dialogFormData.beginDate = begindateObj.value;
    // dialogFormData.endDate = endDateObj.value;
    // @ts-ignore
    const resData = await editWikiMsg(dialogFormData).finally(() => {
      // 无论表单提交是否成功，都执行
      dialogTableVisible.value = false;
      loading.value = false;
      Object.assign(dialogFormData, initDialogFormData());
    });
    if (resData.data.code == 200) {
      ElMessage.success(resData.data.msg);
      await getDemandsList(); //重新获取所有wiki数据
    } else {
      ElMessage.error(resData.data.msg);
      throw new Error();
    }
  }
};

// 取消/关闭添加/修改需求
const handleCancel = () => {
  dialogTableVisible.value = false;
  loading.value = false;
  Object.assign(dialogFormData, initDialogFormData());
};
const handleBeforeCancel = (done: any) => {
  dialogTableVisible.value = false;
  loading.value = false;
  Object.assign(dialogFormData, initDialogFormData());
  done();
};

// 查看wiki详细信息
const handleViewRequire = async (wikiMsg: any) => {
  const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
  let wiki;
  if (typeof wikiMsg != "number") {
    wiki = wikiMsg.ID;
  } else {
    wiki = wikiMsg;
  }

  // 加载wiki数据
  const resData = await getWikiMsg(wiki);
  const data = resData.data.data;

  if (resData.data.code === 7) {
    ElMessage.error(resData.data.msg);
    throw new Error();
  }

  // 获取wiki类型名称
  const resWikiTypeData = await getWikiTypeById(data.itemWIKITypeId);
  if (resData.data.code === 7) {
    ElMessage.error(resData.data.msg);
    throw new Error();
  }

  // 准备展示数据
  const wikiDetailData = {
    id: wiki,
    createUser: data.createUser,
    projectName: data.projectName,
    processingDate: data.processingDate,
    beginDate: tableTimeDateMsg(data.beginDate),
    endDate: tableTimeDateMsg(data.endDate),
    auxiliaryUser: data.auxiliaryUser,
    developmentBBTime: data.developmentBBTime,
    isTrue: data.isTrue,
    isArchiving: data.isArchiving,
    archivingUrl: data.archivingUrl,
    problemReason: data.problemReason,
    trueResult: data.trueResult,
    problemMsg: data.problemMsg,
    problemPhoto: removeEmptyLines(data.problemPhoto),
    itemWIKITypeName: resWikiTypeData.data.data.typeName
  };

  // 根据设备类型选择展示方式
  if (isMobile) {
    // 移动端 - 跳转到详情页
    router.push(`/wiki/${wiki}`);
  } else {
    // PC端 - 使用弹窗展示
    Object.assign(dialogViewData, wikiDetailData);
    dialogViewVisible.value = true;
    // 打开详情的时候注册事件查看图片大图
    nextTick(() => {
      addImageClickHandler();
    });
  }
};

// 为图片添加点击事件监听器
const addImageClickHandler = () => {
  if (content.value) {
    const images = content.value.querySelectorAll("img");
    images.forEach((img) => {
      img.addEventListener("click", () => {
        currentImageSrc.value = img.src;
        dialogVisible.value = true;
      });
    });
  }
};

// 确认删除需求
const handleDelRequire = async (id: number) => {
  const resData = await delWiki(id);
  if (resData.data.code === 200) {
    ElMessage.success(resData.data.msg);
    await getDemandsList();
  } else {
    ElMessage.error(resData.data.msg);
    throw new Error();
  }
};
// 取消删除需求
const handleCancelDel = () => {
  ElMessage.info("取消删除！");
  return;
};

// 开启评分弹窗
const handleRating = (wikiId: number) => {
  // 查找当前wiki的评分信息
  const currentWiki = demandsList.value.find((item: any) => item.ID === wikiId);
  
  ratingFormData.wikiId = wikiId;
  // 如果已有评分，显示现有评分信息
  if (currentWiki && currentWiki.wikiRateUser) {
    // 回显已有的评分和评价
    ratingFormData.score = currentWiki.wikiRate || 0;
    ratingFormData.comment = currentWiki.wikiComment || '';
  } else {
    ratingFormData.score = 2;
    ratingFormData.comment = '';
  }
  dialogRatingVisible.value = true;
};

// 获取当前wiki信息
const getCurrentWikiInfo = () => {
  if (ratingFormData.wikiId) {
    return demandsList.value.find((item: any) => item.ID === ratingFormData.wikiId);
  }
  return null;
};

// 获取当前wiki的评价人
const getCurrentWikiRateUser = () => {
  const currentWiki = getCurrentWikiInfo();
  return currentWiki?.wikiRateUser || '';
};

// 获取评分弹窗标题
const getRatingDialogTitle = () => {
  if (ratingFormData.wikiId) {
    const currentWiki = demandsList.value.find((item: any) => item.ID === ratingFormData.wikiId);
    return currentWiki && currentWiki.wikiRateUser ? 'Wiki评价详情' : 'Wiki评分';
  }
  return 'Wiki评分';
};

// 关闭评分弹窗
const closeRatingDialog = () => {
  dialogRatingVisible.value = false;
  ratingFormData.wikiId = null;
  ratingFormData.score = 2;
  ratingFormData.comment = '';
};

// 提交评分
const submitRating = async () => {
  if (ratingFormData.score === 0) {
    ElMessage.warning('请选择评分！');
    return;
  }
  
  try {
    loading.value = true;
    const resData = await WikiRate({
      wikiId: ratingFormData.wikiId,
      wikiRate: ratingFormData.score,
      wikiComment: ratingFormData.comment
    });
    
    if (resData.data.code === 200) {
      ElMessage.success('评分提交成功！');
      closeRatingDialog();
      await getDemandsList(); // 刷新列表
    } else {
      ElMessage.error(resData.data.msg || '评分提交失败！');
    }
  } catch (error) {
    ElMessage.error('评分提交失败！');
    console.error('评分提交错误:', error);
  } finally {
    loading.value = false;
  }
};

// 表格自适应高度
const tableHeight = ref(480);
const getElementHeight = (selector: string): number => {
  const el = document.querySelector(selector) as HTMLElement | null;
  return el ? el.getBoundingClientRect().height : 0;
};
const recalcTableHeight = () => {
  const viewport = window.innerHeight;
  const paginationH = getElementHeight('.pagination-container') || 48;
  const safePadding = 16; // 表格容器内部与底部的安全内边距（减小以获得更多可用高度）

  // 优先基于表格容器到视口底部的剩余空间计算
  const tableContainer = document.querySelector('.table-container') as HTMLElement | null;
  if (tableContainer) {
    const top = tableContainer.getBoundingClientRect().top;
    const available = viewport - top - paginationH - safePadding;
    const minHeight = viewport <= 768 ? 300 : viewport <= 900 ? 360 : 420; // 上调的最小高度
    tableHeight.value = Math.max(minHeight, available);
    return;
  }

  // 兜底：回退到基于各区块高度的估算
  const searchH = getElementHeight('.search-section');
  const headerH = getElementHeight('.content-header');
  const verticalPadding = 48;
  const available = viewport - (searchH + headerH + paginationH + verticalPadding);
  const minHeight = viewport <= 768 ? 300 : viewport <= 900 ? 360 : 420;
  tableHeight.value = Math.max(minHeight, available);
};

// 初始与窗口变化时计算
onMounted(() => {
  // 首次进入页面：初始化下拉与列表数据
  getProjectOptons();
  getWikiTypeOptons();
  getAllTestOptions();
  getDemandsList();

  nextTick(() => {
    recalcTableHeight();
    window.addEventListener('resize', recalcTableHeight);
  });
});
onUnmounted(() => {
  window.removeEventListener('resize', recalcTableHeight);
});

// 数据加载或筛选后也重新计算高度
watch([loading, () => demandsList.value.length], () => nextTick(recalcTableHeight));

onActivated(() => {
  getDemandsList();
});

</script>

<style scoped lang="scss">
/* 主容器 */
.wiki-view {
  min-height: 100vh;
  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
  padding: 20px;
}

/* 搜索区域 */
.search-section {
  background: #ffffff;
  border-radius: 16px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
  margin-bottom: 24px;
  overflow: hidden;
  backdrop-filter: blur(20px);
  border: 1px solid rgba(255, 255, 255, 0.2);
}

.search-container {
  padding: 24px;
}

.search-form {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.search-row {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  align-items: flex-end;
}

.search-item {
  margin-bottom: 0 !important;
  flex: 0 0 auto;
  
  .el-form-item__label {
    font-weight: 600;
    color: #374151;
    margin-bottom: 8px;
    min-width: 80px;
  }
}

.search-select {
  width: 160px;
  
  :deep(.el-input__wrapper) {
    border-radius: 8px;
    border: 1px solid #e5e7eb;
    transition: all 0.3s ease;
    
    &:hover {
      border-color: #3b82f6;
    }
    
    &.is-focus {
      border-color: #3b82f6;
      box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
    }
  }
}

.search-input {
  width: 200px;
  
  :deep(.el-input__wrapper) {
    border-radius: 8px;
    border: 1px solid #e5e7eb;
    transition: all 0.3s ease;
    
    &:hover {
      border-color: #3b82f6;
    }
    
    &.is-focus {
      border-color: #3b82f6;
      box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
    }
  }
}

.search-date {
  width: 280px;
  
  :deep(.el-input__wrapper) {
    border-radius: 8px;
    border: 1px solid #e5e7eb;
    transition: all 0.3s ease;
    
    &:hover {
      border-color: #3b82f6;
    }
    
    &.is-focus {
      border-color: #3b82f6;
      box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
    }
  }
}

.search-actions {
  display: flex;
  gap: 12px;
  align-items: center;
  margin-left: auto;
}

.search-btn {
  background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
  border: none;
  border-radius: 8px;
  padding: 10px 20px;
  font-weight: 600;
  transition: all 0.3s ease;
  
  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 25px rgba(59, 130, 246, 0.3);
  }
}

.export-btn {
  background: linear-gradient(135deg, #10b981 0%, #059669 100%);
  border: none;
  border-radius: 8px;
  padding: 10px 16px;
  font-weight: 600;
  transition: all 0.3s ease;
  
  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 25px rgba(16, 185, 129, 0.3);
  }
}

/* 内容区域 */
.content-section {
  background: #ffffff;
  border-radius: 16px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
  overflow: hidden;
  backdrop-filter: blur(20px);
  border: 1px solid rgba(255, 255, 255, 0.2);
  display: flex;
  flex-direction: column;
  min-height: 40vh;
}

.content-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 24px 24px 0;
  border-bottom: 1px solid #f3f4f6;
  margin-bottom: 24px;
}

.header-title {
  h2 {
    margin: 0;
    font-size: 24px;
    font-weight: 700;
    color: #111827;
    background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
  }
  
  .subtitle {
    display: block;
    margin-top: 4px;
    font-size: 14px;
    color: #6b7280;
    font-weight: 500;
  }
}

.header-actions {
  .add-btn {
    background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
    border: none;
    border-radius: 8px;
    padding: 12px 24px;
    font-weight: 600;
    transition: all 0.3s ease;
    
    &:hover {
      transform: translateY(-2px);
      box-shadow: 0 8px 25px rgba(59, 130, 246, 0.3);
    }
  }
}

/* 表格容器 */
.table-container {
  padding: 0 24px 24px;
  flex: 1 1 auto;
  min-height: 200px;
}

/* 表格样式 */
:deep(.el-table) {
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
  
  .el-table__header {
    background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
    
    th {
      background: transparent;
      color: #374151;
      font-weight: 600;
      border-bottom: 2px solid #e5e7eb;
    }
  }
  
  .el-table__body {
    tr {
      transition: all 0.3s ease;
      
      &:hover {
        background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);
        transform: translateY(-1px);
        box-shadow: 0 4px 12px rgba(59, 130, 246, 0.1);
      }
    }
    
    td {
      border-bottom: 1px solid #f3f4f6;
      padding: 16px 12px;
    }
  }
}

.user-name {
  font-weight: 600;
  color: #3b82f6;
}

/* 表格操作按钮 */
.table-actions {
  display: flex;
  gap: 8px;
  justify-content: center;
}

.action-btn {
  border-radius: 6px;
  font-weight: 500;
  transition: all 0.3s ease;
  
  &.view-btn {
    background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
    border: none;
    
    &:hover {
      transform: translateY(-1px);
      box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);
    }
  }
  
  &.edit-btn {
    background: linear-gradient(135deg, #6b7280 0%, #4b5563 100%);
    border: none;
    
    &:hover {
      transform: translateY(-1px);
      box-shadow: 0 4px 12px rgba(107, 114, 128, 0.3);
    }
  }
  
  &.delete-btn {
    background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
    border: none;
    
    &:hover {
      transform: translateY(-1px);
      box-shadow: 0 4px 12px rgba(239, 68, 68, 0.3);
    }
  }
  
  &.rating-btn {
    background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
    border: none;
    
    &:hover {
      transform: translateY(-1px);
      box-shadow: 0 4px 12px rgba(245, 158, 11, 0.3);
    }
  }
  
  &.rated-btn {
    background: linear-gradient(135deg, #10b981 0%, #059669 100%);
    border: none;
    
    &:hover {
      transform: translateY(-1px);
      box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3);
    }
  }
}

/* 分页容器 */
.pagination-container {
  padding: 24px;
  border-top: 1px solid #f3f4f6;
  display: flex;
  justify-content: flex-end;
}

/* 弹窗样式 */
.modern-dialog {
  :deep(.el-dialog) {
    border-radius: 16px;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15);
    overflow: hidden;
    
    .el-dialog__header {
      background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
      padding: 20px 24px;
      border-bottom: 1px solid #e5e7eb;
      
      .el-dialog__title {
        font-weight: 600;
        color: #111827;
      }
    }
    
    .el-dialog__body {
      padding: 24px;
    }
    
    .el-dialog__footer {
      padding: 16px 24px;
      border-top: 1px solid #f3f4f6;
      background: #fafafa;
    }
  }
}

/* 查看详情弹窗 */
.view-content {
  background: #fff;
  padding: 0 10px;
  
  .el-row {
    border-left: 1px solid #e5e7eb;
    border-right: 1px solid #e5e7eb;
    text-align: left;
  }
  
  .el-col {
    border: 1px solid #e5e7eb;
    padding: 12px 16px;
    background: #fafafa;
  }
}

.dialog-view-requireTitle {
  font-weight: 600;
  color: #374151;
}

/* 操作按钮 */
.table-operation {
  width: 36px;
  height: 26px;
  padding: 0 10px;
  display: inline-block;
  color: #409eff;
  border-radius: 6px;
  transition: all 0.3s ease;
}

.table-operation-view:hover,
.table-operation-edit:hover {
  background-color: #409eff;
  color: white;
  transform: translateY(-1px);
}

.table-operation-del:hover {
  background-color: #ff343f;
  color: white;
  transform: translateY(-1px);
}

/* 文本溢出省略 */
.cell-ellipsis {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 图片查看器 */
.page-shade {
  background-color: rgba(0, 0, 0, 0.8);
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 99999;
  overflow: hidden;
  backdrop-filter: blur(10px);
}

.img-big {
  padding: 20px;
  height: 100vh;
  overflow: auto;
  cursor: pointer;
  width: 100vw;
  display: flex;
  justify-content: center;
  align-items: center;
}

.img-big img {
  cursor: pointer;
  vertical-align: middle;
  max-width: 80%;
  max-height: 80%;
  border-radius: 8px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
}

/* 响应式设计 */
@media (max-width: 768px) {
  .wiki-view {
    padding: 12px;
  }
  
  .search-form {
    gap: 16px;
  }
  
  .search-row {
    flex-direction: column;
    gap: 16px;
    align-items: stretch;
  }
  
  .search-item {
    width: 100%;
    
    .el-form-item__label {
      min-width: auto;
    }
  }
  
  .search-select,
  .search-input,
  .search-date {
    width: 100%;
  }
  
  .search-actions {
    margin-left: 0;
    flex-wrap: wrap;
    justify-content: center;
  }
  
  .content-header {
    flex-direction: column;
    gap: 16px;
    align-items: flex-start;
  }
  
  .table-actions {
    flex-direction: column;
    gap: 4px;
  }
}
</style>

<style lang="scss">
/* 全局样式覆盖 */
.el-table {
  --el-table-row-hover-bg-color: #f0f9ff;
  --el-table-border-color: #e5e7eb;
  --el-table-header-bg-color: #f8fafc;
}

.el-dialog {
  --el-dialog-margin-top: 5vh;
  --el-dialog-border-radius: 16px;
}

.el-dialog__body {
  padding: 24px;
}

.el-button {
  border-radius: 8px;
  font-weight: 500;
  transition: all 0.3s ease;
}

.el-input__wrapper {
  border-radius: 8px;
  transition: all 0.3s ease;
}

.el-select {
  .el-input__wrapper {
    border-radius: 8px;
  }
}

.el-tag {
  border-radius: 6px;
  font-weight: 500;
}

/* 滚动条样式 */
::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

::-webkit-scrollbar-track {
  background: #f1f5f9;
  border-radius: 4px;
}

::-webkit-scrollbar-thumb {
  background: #cbd5e1;
  border-radius: 4px;
  
  &:hover {
    background: #94a3b8;
  }
}
</style>
